#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import json
from pypinyin import lazy_pinyin
from flask_login import login_required
from flask_restful import Resource, reqparse
from sqlalchemy.orm.util import join
from werkzeug.utils import secure_filename
from werkzeug.datastructures import CombinedMultiDict
from my_app import ALLOWED_EXTENSIONS, db, api, app
from my_app.catalog.models import Product, Category, ProductForm, CategoryForm
from my_app.auth.models import User
from my_app.auth.views import current_user
from flask import flash, redirect, url_for, render_template, request, Blueprint, abort


# 定义catalog的蓝图，模块化
catalog = Blueprint("catalog", __name__)


@catalog.route("/")
@catalog.route("/home")
def home():
    return render_template('home.html')


@catalog.route("/product/<id>")
@login_required
def product(id):
    # 根据产品id查询产品，查不到则返回404
    _product = Product.query.get_or_404(id)
    return render_template('products/product.html', product=_product)


@catalog.route("/products")
@catalog.route("/products/<int:page>")
@login_required
def products(page=1):
    # 返回每个用户的数据并分页，每页10条数据，降序排列
    # if current_user.username == "admin":
    #     _products = Product.query.filter().order_by(Product.id.desc()).paginate(page, 10)
    # else:
    #     _products = Product.query.filter(
    #         Product.user_id == current_user.id
    #     ).order_by(Product.id.desc()).paginate(page, 10)
    _products = Product.query.filter().order_by(Product.id.desc()).paginate(page, 10)
    # 将查询出的数据渲染至products模板中，关键字products为模板中使用的products
    return render_template('products/products.html', products=_products)


@catalog.route("/product-search", methods=['POST', "GET"])
@catalog.route("/product-search/<int:page>")
@login_required
def product_search(page=1):
    """搜索"""
    name = request.args.get('name')
    price = request.args.get('price')
    _category = request.args.get('category')
    _products = Product.query
    # 使用搜索框内容模糊、精准查询
    content = request.form.get('content')
    _products = _products.filter(Product.name.like('%' + content + '%'))
    # 使用 name、price、category的值，精准或模糊查询
    if name:
        _products = _products.filter(Product.name.like('%' + name + '%'))
    if price:
        _products = _products.filter(Product.price == price)
    if _category:
        _products = _products.select_from(join(Product, Category)).filter(Category.name.like('%' + _category + '%'))
    return render_template('products/products.html', products=_products.paginate(page, 10))


def allowed_file(filename):
    # 检查文件后缀名是否合规
    return '.' in filename and filename.lower().split('.')[1] in ALLOWED_EXTENSIONS


@catalog.route("/product-create", methods=['POST', 'GET'])
@login_required
def create_product():
    form = ProductForm(CombinedMultiDict([request.form, request.files]))
    _categories = [(c.id, c.name) for c in Category.query.all()]
    form.category.choices = _categories
    if form.validate_on_submit():
        name = form.name.data
        price = form.price.data
        _category = Category.query.get_or_404(form.category.data)  # _category.id 获取分组ID
        _user_id = User.query.get_or_404(current_user.id)
        image = form.image.data
        if allowed_file(filename=image.filename):
            filename = secure_filename("".join(lazy_pinyin(image.filename)))
            image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        _product = Product(name, price, _category, filename, _user_id)
        db.session.add(_product)
        db.session.commit()
        flash('创建产品 {} ，成功'.format(name))
        return redirect(url_for('catalog.products', id=_product.id))

    if form.errors:
        flash(form.errors, 'danger')
    return render_template('products/product-create.html', form=form)


@catalog.route("/product-update/<id>", methods=['POST', 'GET'])
@login_required
def update_product(id):
    _product = Product.query.get_or_404(id)
    form = ProductForm(CombinedMultiDict([request.form, request.files]), obj=_product)  # obj=_product 将原有的数据带出
    _categories = [(c.id, c.name) for c in Category.query.all()]
    form.category.choices = _categories
    if form.validate_on_submit():
        _product.name = form.name.data
        _product.price = form.price.data
        _product.category = Category.query.get_or_404(form.category.data)
        _product.image = form.image.data
        if allowed_file(filename=_product.image.filename):
            filename = secure_filename("".join(lazy_pinyin(_product.image.filename)))
            _product.image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            _product.image_path = "".join(lazy_pinyin(_product.image.filename))
        db.session.add(_product)
        db.session.commit()
        return redirect(url_for('catalog.products', id=_product.id))

    if form.errors:
        flash(form.errors, 'danger')
    return render_template("products/product-update.html", product=_product, form=form)


@catalog.route("/product-delete/<id>")
@login_required
def delete_product(id):
    _product = Product.query.get_or_404(id)
    db.session.delete(_product)
    db.session.commit()
    return redirect(url_for('catalog.products'))


@catalog.route("/category-create", methods=["POST", "GET"])
@login_required
def create_category():
    form = CategoryForm(csrf_enabled=False)
    if form.validate_on_submit():
        name = form.name.data
        _user_id = User.query.get_or_404(current_user.id)  # 查询user_id
        _category = Category(name, _user_id)
        db.session.add(_category)
        db.session.commit()
        flash(f"{name}，分组创建成功")
        return redirect(url_for('catalog.category', id=_category.id))
    if form.errors:
        flash(form.errors)
    return render_template('products/category-create.html', form=form)


@catalog.route('/category/<id>')
@login_required
def category(id):
    _category = Category.query.get_or_404(id)
    return render_template('products/category.html', category=_category)
    # if _category.user.id == current_user.id:
    #     return render_template('category.html', category=_category)
    # else:
    #     abort(404, "该分组不属于当前登录用户，无权限访问！")


@catalog.route("/categories")
@login_required
def categories():
    _categories = Category.query.all()
    return render_template('products/categories.html', categories=_categories)


"""REST ful API"""
# 为post和put请求中需要的参数创建了parse，如果参数值缺失，对应值则表示未none
parser = reqparse.RequestParser()
parser.add_argument('name', type=str)
parser.add_argument('price', type=float)
parser.add_argument('category', type=dict)
parser.add_argument('image_path', type=str)


class ProductApi(Resource):

    def get(self, id=None, page=1):
        """返回产品数据"""
        if not id:
            products = Product.query.paginate(page, 10).items
        else:
            products = [Product.query.get(id)]
        if not products:
            abort(404)
        res = {}
        for product in products:
            res[product.id] = {'name': product.name, 'price': product.price, 'category': product.category.name}
        return json.dumps(res)

    def post(self):
        """创建一个产品"""
        args = parser.parse_args()
        name = args['name']
        price = args['price']
        category_name = args['category']['name']
        image_path = args['image_path']
        category = Category.query.filter_by(name=category_name).first()
        if not category:
            category = Category(category_name)
        product = Product(name, price, category, image_path)
        db.session.add(product)
        db.session.commit()
        res = {product.id: {'name': product.name, 'price': product.price, 'category': product.category.name, 'image': product.image_path}}
        return json.dumps(res)

    def put(self, id):
        """使用指定的产品id更新产品"""
        return "这是一个put响应"

    def delete(self, id):
        """使用指定的id删除产品"""
        return "这是一个delete响应"


# 创建路由机制
api.add_resource(ProductApi, '/api/products', '/api/products/<int:id>', '/api/products/<int:id>/<int:page>')



